﻿using System;
using System.Collections.Generic;
using System.Linq;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing; //Point
using System.Threading;
using System.Drawing.Imaging;

namespace Nero_demo
{
    class WindowHelper
    {
        #region 根据句柄寻找窗体并发送消息

        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        //参数1:指的是类名。参数2，指的是窗口的标题名。两者至少要知道1个
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern IntPtr SetWindowText(IntPtr hWnd, string lpString);

        [DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);
        [DllImport("User32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        private const int SW_HIDE = 0;
        private const int SW_SHOWNORMAL = 1;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_SHOWMAXIMIZED = 3;
        private const int SW_MAXIMIZE = 3;
        private const int SW_SHOWNOACTIVATE = 4;
        private const int SW_SHOW = 5;
        private const int SW_MINIMIZE = 6;
        private const int SW_SHOWMINNOACTIVE = 7;
        private const int SW_SHOWNA = 8;
        private const int SW_RESTORE = 9;
        #endregion

        #region 获取窗体位置
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;                             //最左坐标
            public int Top;                             //最上坐标
            public int Right;                           //最右坐标
            public int Bottom;                        //最下坐标
        }
        #endregion

        #region 截图
        public void ScreenShot(string fileName)
        {
            string filePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "snapshot\\";//获取应用程序运行的路径
            try
            {
                Screen screen = Screen.AllScreens.FirstOrDefault();//获取当前第一块屏幕(根据需求也可以换其他屏幕)
                //创建需要截取的屏幕区域  
                Rectangle rc = new Rectangle(leftBase, topBase, winWidth, winHeight);
                //生成截图的位图容器  
                Bitmap bitmap = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb);
                //GDI+图像画布  
                using (Graphics memoryGrahics = Graphics.FromImage(bitmap))
                {
                    memoryGrahics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy);//对屏幕指定区域进行图像复制
                }
                bitmap.Save(filePath + fileName, ImageFormat.Png);
                // logEvent("文件保存在:" + filePath + fileName);
            }
            catch (Exception ex)
            {
                //异常处理
                LogHelper.Record(ex.ToString());
            }
        }

        public Mat ScreenShot()
        {
            if (Program.MainFram.InvokeRequired)
            {
                return (Mat)Program.MainFram.Invoke(new Func<Mat>(ScreenShot));
            }
            Mat result = null;
            try
            {
                Screen screen = Screen.AllScreens.FirstOrDefault();//获取当前第一块屏幕(根据需求也可以换其他屏幕)
                //创建需要截取的屏幕区域  
                Rectangle rc = new Rectangle(leftBase, topBase, winWidth, winHeight);
                //生成截图的位图容器  
                Bitmap bitmap = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb);
                //GDI+图像画布  
                using (Graphics memoryGrahics = Graphics.FromImage(bitmap))
                {
                    memoryGrahics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy);//对屏幕指定区域进行图像复制
                }
                result = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
                Cv2.CvtColor(result, result, ColorConversionCodes.RGBA2RGB);//mat转三通道mat
                // logEvent("文件保存在:" + filePath + fileName);
            }
            catch (Exception ex)
            {
                //异常处理
                LogHelper.Record(ex.ToString());
            }

            return result;
        }
        #endregion

        public bool InitWindow(string name)
        {
            awin = FindWindow(null, name);

            if (awin == IntPtr.Zero)
            {
                // logEvent("没有找到窗口");
                return false;
            }

            // logEvent("找到窗口");

            RECT rc = new RECT();
            GetWindowRect(awin, ref rc);
            // logEvent(string.Format("left={0},top={1},right={2},bottom={3}", rc.Left, rc.Top, rc.Right, rc.Bottom));

            leftBase = rc.Left;
            topBase = rc.Top;
            winWidth = rc.Right - rc.Left;
            winHeight = rc.Bottom - rc.Top;

            SetForegroundWindow(awin);
            ShowWindow(awin, SW_SHOWNOACTIVATE);

            Thread.Sleep(200);
            return true;
        }

        public void SetWindowName(string name)
        {
            SetWindowText(awin, name);
        }

        public int leftBase { get; private set; }
        public int topBase { get; private set; }
        public int winWidth { get; private set; }
        public int winHeight { get; private set; }

        private IntPtr awin;  // 窗口句柄

    }
}
